<template>

  <div class="app-container">

    <el-row>
      <el-button type="primary" @click="resetStage">清除画布</el-button>
      <el-button type="primary" @click="preStage">上一步</el-button>
      <el-button type="primary" @click="animationStage">{{ animation?"停止动画":"开始动画" }}</el-button>
      <el-button type="primary" @click="jsonData">json数据</el-button>
    </el-row>
    <!--<el-row>
      当前json数据：<span>{{ stageData ? JSON.stringify(stageData) :"" }}</span>
    </el-row>-->
    <div class="content">
      <div class="dragIcon" @dragstart="handleDragStart">
        <div v-for="(item, index) in iconList" :key="index" :data-index="index" class="list" draggable>
          <span :class="item.icon" class="iconfont" :title="item.label" />
        </div>
      </div>
      <div id="dragContent" class="dragContent" @mouseenter="handleMouseDown1" />
    </div>

  </div>

</template>

<script>
import Konva from 'konva'
export default {
  name: 'Drag',
  data() {
    return {
      iconList: [
        {
          icon: 'icon-zhujiexiantu',
          label: '测试1',
          type: 'img',
          img: require('@/assets/jt.png')
        },
        {
          icon: 'icon-dianlihangye',
          label: '测试2',
          type: 'img',
          img: require('@/assets/sxt.png')
        },
        {
          icon: 'icon-lightning-full',
          label: '测试3',
          type: 'img',
          img: require('@/assets/xx.png')
        }
      ],
      // 舞台对象
      stage: null,
      // 保存layer
      layer: null,
      // 当前被拖动对象icon
      currIcon: null,
      // 保存舞台数据
      stageData: [],
      appHistory: [],
      appHistoryStep: 0,
      animation: false,
      atimer: null,
      currNode: null
    }
  },
  mounted() {
    this.initDrag()
  },
  methods: {
    jsonData() {
      this.$message.info(JSON.stringify(this.stageData))
    },
    // 动画
    animationStage() {
      this.animation = !this.animation
      clearInterval(this.atimer)
      const node = this.stage.findOne('.item-0')
      if (!this.animation) {
        console.log('停止动画')
        node.brightness(0)
        return
      }

      let value = 0.5
      if (node) {
        this.atimer = setInterval(() => {
          node.cache()
          node.filters([Konva.Filters.Brighten])
          node.brightness(value)
          value = value === 0 ? 0.5 : 0
          this.layer.batchDraw()
        }, 300)
      } else {
        this.$message.info('没用动画节点')
      }
    },
    // 上一步
    preStage() {
      if (this.appHistoryStep === 0) {
        return
      }
      this.appHistoryStep -= 1
      this.stageData = this.appHistory[this.appHistoryStep]
      this.createLayer(this.stageData)
    },
    // 重新绘制
    resetStage() {
      // this.stage.clear()
      // console.log('======================重新绘制')
      /* if (this.appHistoryStep === this.appHistory.length - 1) {
        // console.log('================1212======重新绘制')
        return
      }
      this.appHistoryStep += 1
      this.stageData = this.appHistory[this.appHistoryStep]
      // create everything from scratch
      this.createLayer()*/

      this.stage.clear()
      this.stageData = []
      this.appHistory = []
      this.appHistoryStep = 0
    },
    handleDragStart(e) {
      e.dataTransfer.setData('index', e.target.dataset.index)
      this.currIcon = this.iconList[e.target.dataset.index]
    },
    // 渲染图片
    handleMouseDown1(e) {
      if (!this.currIcon) {
        return
      }
      const { type, img } = this.currIcon
      const x = e.offsetX
      const y = e.offsetY

      // console.log('img: ' + img)

      // const url = require(this.currIcon.img)
      // console.log('img: ' + url)
      this.stageData.push({
        x,
        y,
        type,
        url: img,
        scaleX: 1,
        scaleY: 1
      })
      this.currIcon = ''
      // recreate canvas
      this.createLayer(this.stageData)
      /* const _this = this

      const layer = new Konva.Layer()
      let json = ''
      var imageObj = new Image()
      imageObj.onload = function() {
        const yoda = new Konva.Image({
          x: x,
          y: y,
          image: imageObj,
          width: 50,
          height: 50,
          draggable: true
        })
        layer.add(yoda)
        layer.draw()
        /!* const tr1 = new Konva.Transformer({
          node: yoda,
          centeredScaling: true
        })*!/
        /!* yoda.on('click', function() {
          console.log('mouseover===============')
        })*!/
        // layer.add(tr1)

        json = _this.stage.toJSON()
      }
      imageObj.src = require('../../assets/usericon.png')
      this.currIcon = null
      this.stage.add(layer)

      /!* setTimeout(() => {
        this.stage.clear()
      }, 3000)*!/

      setTimeout(() => {
        console.log('=================reload==============')
        // console.log(json)
        var json1 =
          '{"attrs":' +
          '{"width":578,"height":200},' +
          '"className":"Stage",' +
          '"children":[' +
          '{"attrs":{},' +
          '"className":"Layer",' +
          '"children":[{"attrs":' +
          '{"x":100,"y":100,"sides":6,' +
          '"radius":70,"fill":"red","stroke":"black","strokeWidth":4},"className":"RegularPolygon"}]}]}'
        console.log('=================json==============')
        console.log(JSON.parse(json))
        console.log('=================json1==============')
        console.log(JSON.parse(json1))
        // create node using json string
        this.stage = Konva.Node.create(json, 'dragContent')
      }, 6000)*/
    },
    // 初始化舞台
    initDrag() {
      this.stage = new Konva.Stage({
        container: 'dragContent',
        width: 1000,
        height: 700
      })

      this.layer = new Konva.Layer()
      this.stage.add(this.layer)
      // 请求接口 获取数据 ？？
      this.stageData = [
        { x: 150, y: 150, url: require('@/assets/jt.png'), type: 'img', scaleX: 1, scaleY: 1 }
      ]
      // 用于回退操作
      this.appHistory = [this.stageData]
      this.appHistoryStep = 0
      // 处理数据
      this.createLayer()

      this.stage.on('click tap', (e) => {
        // if click on empty area - remove all transformers
        if (e.target === this.stage) {
          if (this.stage.find('Transformer') && this.stage.find('Transformer').length > 0) {
            this.stage.find('Transformer')[0].destroy()
            this.layer.draw()
          }
          return
        }
      })

      const container = this.stage.container()
      container.tabIndex = 1
      // focus it
      // also stage will be in focus on its click
      container.focus()

      const _this = this
      container.addEventListener('keydown', function(e) {
        console.log(e.keyCode)
        if (e.keyCode === 8) {
          console.log('移除：')
          if (_this.currNode.node) {
            _this.stage.find('Transformer')[0].destroy()
            _this.currNode.node.destroy()
            _this.layer.batchDraw()
            _this.stageData = _this.stageData.slice()
            _this.stageData = _this.stageData.length === 1 ? [] : _this.stageData.splice(_this.currNode.index, 1)
            _this.saveStageToHistory(_this.stageData)
          }
        }
        e.preventDefault()
      })
    },
    // 保存下一步的舞台数据
    saveStageToHistory() {
      this.appHistory = this.appHistory.slice(0, this.appHistoryStep + 1)
      this.appHistory = this.appHistory.concat([this.stageData])
      this.appHistoryStep += 1
    },
    updateLayer() {
      this.stageData.forEach((item, index) => {
        const node = this.stage.findOne('.item-' + index)
        node.setAttrs({
          x: item.x,
          y: item.y
        })
        if (!node.image()) {
          return
        }
        if (item.filter === 'blur') {
          node.filters([Konva.Filters.Blur])
          node.blurRadius(10)
          node.cache()
        } else if (item.filter === 'invert') {
          node.filters([Konva.Filters.Invert])
          node.cache()
        } else {
          node.filters([])
          node.clearCache()
        }
      })
      this.layer.batchDraw()
    },
    createLayer() {
      this.layer.destroyChildren()
      const _this = this
      console.log(this.stageData)
      this.stageData.forEach((item, index) => {
        if (item.type === 'img') { // 创建图片
          const node = new Konva.Image({
            draggable: true,
            name: 'item-' + index,
            scaleX: item.scaleX,
            scaleY: item.scaleY,
            x: item.x,
            y: item.y
          })
          _this.layer.add(node)
          node.on('dragend', () => {
            this.stageData = this.stageData.slice()
            this.stageData[index] = Object.assign({}, this.stageData[index], {
              x: node.x(),
              y: node.y()
            })
            this.saveStageToHistory(this.stageData)
          })

          node.on('click', () => {
            // 点击事件
            console.log('点击事件')
            const tr2 = new Konva.Transformer({
              node: node,
              centeredScaling: false
            })
            _this.layer.add(tr2)
            _this.currNode = {
              node: node,
              index: index
            }
            console.log('当前选中对象')
            console.log(_this.currNode)
          })

          node.on('transformend', () => {
            this.stageData = this.stageData.slice()
            this.stageData[index] = Object.assign({}, this.stageData[index], {
              scaleX: node.scaleX(),
              scaleY: node.scaleY()
            })
            this.saveStageToHistory(this.stageData)
          })

          const img = new window.Image()
          img.onload = function() {
            node.image(img)
            _this.updateLayer()
            _this.layer.batchDraw()
          }
          img.src = item.url
        } else {
          // 创建其他的 ...
        }
      })

      this.updateLayer()
    }
  }
}
</script>

<style scoped lang="scss">
  .content{
    width: 1280px;
    height: 700px;
    margin: 50px auto;
    position: relative;
  }
  .dragIcon{
    position: absolute;
    top:0;
    left:0;
    width: 200px;
    height: 100%;
    border: 1px solid #ccc;
    .list {
      width: 45%;
      border: 1px solid #dddddd;
      cursor: grab;
      // margin-bottom: 10px;
      text-align: center;
      color: #333333;
      padding: 2px 5px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin:20px auto;

      &:active {
        cursor: grabbing;
      }

      .iconfont {
        margin-right: 4px;
        font-size: 20px;
      }

      .icon-wenben,
      .icon-tupian {
        font-size: 18px;
      }
    }
  }
  .dragContent{
    position: absolute;
    left:280px;
    top:0;
    width: 1000px;
    height: 700px;
    border: 1px solid #ccc;
  }
</style>
